package com.phychips.serial;

import com.phychips.JniClass;
import com.phychips.common.OnBytesAvailableListener;
import com.phychips.rcp.RcpConst;
import com.phychips.rcp.RcpException;
import com.phychips.rcp.RcpLib;

public class SerialTranceiver {
    // TODO 前5位都是标记头,第五位是EPC的长度,第六位,第七位是PC码，第八位开始才是EPC码，碰到7e就结束读取
    private byte RCP_PRAMBL_LEN = 1;
    private byte RCP_HEADER_LEN = 4;
    private byte RCP_ENDMRK_LEN = 1;
    private byte RCP_HEADEND_LEN = (byte) (RCP_PRAMBL_LEN + RCP_HEADER_LEN + RCP_ENDMRK_LEN);
    private byte RCP_CRC_LEN = 2;
    private byte RCP_HEADEND_CRC_LEN = (byte) (RCP_HEADEND_LEN + RCP_CRC_LEN);

    // TODO 这是原来的
    //  public static final int MAX_BUF = 512;
    public static final int MAX_BUF = 2048;
    private Thread inputThread;

    // TODO 这是最原来的串口
    // static public String comport = new String("/dev/ttyUSB0");
    // TODO 这是老的读写模块串口
    // static public String comport = new String("/dev/ttyS7");
    // TODO 这是新的读写模块串口
    // static public String comport = new String("/dev/ttyS0");
    // TODO 这是最新的读写模块串口，还没做出来
    static public String comport = new String("/dev/ttyS3");

    static public boolean mRunflag = false;

    public void change_comport(String newcomport) {
        comport = new String(newcomport);
    }

    public boolean open() throws RcpException {
        if (JniClass.open(comport) < 0) {
            mRunflag = false;
            return false;
        } else {
            inputThread = new Thread(inputProcessor);
            inputThread.start();

            mRunflag = true;
            return true;
        }
    }

    public void close() throws RcpException {
        if (mRunflag == true)
            JniClass.close();
        mRunflag = false;
    }

    public void send(byte[] data, int length) throws RcpException {
        int res = 0;

        for (int i = 0; res >= 0 && i < length; i++)
            res = JniClass.write(RcpLib.covertUbytetoInt(data[i]));
    }

    private Runnable inputProcessor = new Runnable() {
        public void run() {
            while (mRunflag) {
                try {
                    int recvlen = 0;
                    boolean added = false;
                    int i = 0;
                    int res = 0;
                    int payload_len = 0;
                    byte rbuf[] = new byte[MAX_BUF];

                    //	for (i = 0; res >= 0 && i < MAX_BUF; i++)
                    while (true) {
                        res = JniClass.read();
                        // TODO 读取的Log
                        System.out.println("JniClass.read()：十进制= " + res + " ,\t十六进制= " + Integer.toString(res, 16));

                        if (added) {
                            if (recvlen < (RCP_PRAMBL_LEN + RCP_HEADER_LEN)) {
                                rbuf[recvlen++] = (byte) (res & 0xFF);
                            } else if (recvlen == (RCP_PRAMBL_LEN + RCP_HEADER_LEN)) {
                                rbuf[recvlen++] = (byte) (res & 0xFF);

                                payload_len = RcpLib.convertByteArrayToInt(rbuf, 3, 2);
                            } else {
                                rbuf[recvlen++] = (byte) (res & 0xFF);

                                if (recvlen >= (RCP_HEADEND_CRC_LEN + payload_len)) {
                                    if (rbuf[RCP_PRAMBL_LEN + RCP_HEADER_LEN + payload_len] != RcpConst.ENDMARK)
                                        recvlen = 0;

                                    break;
                                }

                                if (recvlen > MAX_BUF)
                                    break;
                            }
                        } else {
                            if ((byte) (res & 0xFF) == RcpConst.PREAMBLE) {
                                rbuf[recvlen++] = RcpConst.PREAMBLE;
                                added = true;
                            }
                        }
                    }

                    if (recvlen <= RCP_HEADEND_CRC_LEN)
                        continue;
                    else {
                        byte[] ba = new byte[recvlen];

                        for (i = 0; i < ba.length; i++)
                            ba[i] = rbuf[i];

                        notifyBytesAvailable(ba);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {

                }
            }
        }
    };

    private OnBytesAvailableListener bytesAvailableListener = null;

    private void notifyBytesAvailable(byte[] rxData) {
        if (bytesAvailableListener != null) {
            bytesAvailableListener.onBytesAvailable(rxData);
        }
    }

    public void registerBytesAvailableListener(OnBytesAvailableListener listener) {
        bytesAvailableListener = listener;
    }
}
